

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
  <link rel="icon" href="/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="深海火锅店">
  <meta name="keywords" content="">
  
    <meta name="description" content="React介绍 原文请移步Bilibili 作者文档在视频简介内 源码地址：https:&#x2F;&#x2F;gitee.com&#x2F;react-cp&#x2F;react-pc-code  React基础讲义: https:&#x2F;&#x2F;www.yuque.com&#x2F;fechaichai&#x2F;qeamqf&#x2F;xbai87  React和Mobx讲义: https:&#x2F;&#x2F;www.yuque.com&#x2F;fechaichai&#x2F;qeamqf&#x2F;apomum">
<meta property="og:type" content="article">
<meta property="og:title" content="React基础">
<meta property="og:url" content="http://example.com/2023/06/02/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/React/01.React%E5%9F%BA%E7%A1%80/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="React介绍 原文请移步Bilibili 作者文档在视频简介内 源码地址：https:&#x2F;&#x2F;gitee.com&#x2F;react-cp&#x2F;react-pc-code  React基础讲义: https:&#x2F;&#x2F;www.yuque.com&#x2F;fechaichai&#x2F;qeamqf&#x2F;xbai87  React和Mobx讲义: https:&#x2F;&#x2F;www.yuque.com&#x2F;fechaichai&#x2F;qeamqf&#x2F;apomum">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132172.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132535.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132527.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132145.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133365.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133601.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133194.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133508.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133120.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133195.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133457.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133896.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134113.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134670.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134015.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134395.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134115.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134614.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134723.png">
<meta property="og:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134129.png">
<meta property="article:published_time" content="2023-06-01T16:00:00.000Z">
<meta property="article:modified_time" content="2024-02-15T15:59:54.237Z">
<meta property="article:author" content="深海火锅店">
<meta property="article:tag" content="React">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132172.png">
  
  
    <meta name="referrer" content="no-referrer-when-downgrade">
  
  
  <title>React基础 - Hexo</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.9.3","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 6.3.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>Fluid</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/background.jpg') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="React基础"></span>
          
        </div>

        
          
  <div class="mt-3">
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2023-06-02 00:00" pubdate>
          2023年6月2日 凌晨
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          32k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          265 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">React基础</h1>
            
            
              <div class="markdown-body">
                
                <h1 id="React介绍"><a href="#React介绍" class="headerlink" title="React介绍"></a>React介绍</h1><blockquote>
<p>原文请移步<a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Z44y1K7Fj/?spm_id_from=333.337.search-card.all.click&vd_source=0de2cc95ad0adc3e9ec15f6dcede1a20">Bilibili</a></p>
<p>作者文档在视频简介内</p>
<p>源码地址：<a target="_blank" rel="noopener" href="https://gitee.com/react-cp/react-pc-code">https://gitee.com/react-cp/react-pc-code</a> </p>
<p>React基础讲义: <a target="_blank" rel="noopener" href="https://www.yuque.com/fechaichai/qeamqf/xbai87">https://www.yuque.com/fechaichai/qeamqf/xbai87</a> </p>
<p>React和Mobx讲义: <a target="_blank" rel="noopener" href="https://www.yuque.com/fechaichai/qeamqf/apomum">https://www.yuque.com/fechaichai/qeamqf/apomum</a> </p>
<p>ReactPc项目讲义: <a target="_blank" rel="noopener" href="https://www.yuque.com/fechaichai/tzzlh1">https://www.yuque.com/fechaichai/tzzlh1</a></p>
</blockquote>
<p><code>目标任务:</code>  了解什么是React以及它的特点</p>
<p><strong>React是什么</strong></p>
<p>   一个专注于构建用户界面的 JavaScript 库，和vue和angular并称前端三大框架，不夸张的说，react引领了很多新思想，世界范围内是最流行的js前端框架，最新版本已经到了18，加入了许多很棒的新特性</p>
<p>​	React英文文档（<a target="_blank" rel="noopener" href="https://reactjs.org/%EF%BC%89">https://reactjs.org/）</a></p>
<p>​	React中文文档 （<a target="_blank" rel="noopener" href="https://zh-hans.reactjs.org/%EF%BC%89">https://zh-hans.reactjs.org/）</a></p>
<p>​	React新文档（<a target="_blank" rel="noopener" href="https://beta.reactjs.org/%EF%BC%89%EF%BC%88%E5%BC%80%E5%8F%91%E4%B8%AD....%EF%BC%89">https://beta.reactjs.org/）（开发中....）</a></p>
<p><strong>React有什么特点</strong></p>
<p>1- 声明式UI（JSX）</p>
<p>写UI就和写普通的HTML一样，抛弃命令式的繁琐实现</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132172.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p>2- 组件化</p>
<p>组件是react中最重要的内容，组件可以通过搭积木的方式拼成一个完整的页面，通过组件的抽象可以增加复用能力和提高可维护性 </p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132535.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p>3- 跨平台</p>
<p>react既可以开发web应用也可以使用同样的语法开发原生应用（react-native），比如安卓和ios应用，甚至可以使用react开发VR应用，想象力空间十足，react更像是一个 <code>元框架</code>  为各种领域赋能 </p>
<h1 id="环境初始化"><a href="#环境初始化" class="headerlink" title="环境初始化"></a>环境初始化</h1><p><code>目标任务:</code>  能够独立使用React脚手架创建一个react项目</p>
<h2 id="1-使用脚手架创建项目"><a href="#1-使用脚手架创建项目" class="headerlink" title="1. 使用脚手架创建项目"></a>1. 使用脚手架创建项目</h2><p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132527.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<ul>
<li>打开命令行窗口 </li>
<li>执行命令</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npx create-react-app react-basic<br></code></pre></td></tr></table></figure>


<p>说明： </p>
<ol>
<li><ol>
<li>npx create-react-app 是固定命令，<code>create-react-app</code>是React脚手架的名称</li>
<li>react-basic表示项目名称，可以自定义，保持语义化</li>
<li>npx 命令会帮助我们临时安装create-react-app包，然后初始化项目完成之后会自自动删掉，所以不需要全局安装create-react-app</li>
</ol>
</li>
</ol>
<ul>
<li>启动项目</li>
</ul>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ yarn start<br>or<br>$ npm start<br></code></pre></td></tr></table></figure>

<h2 id="2-项目目录说明调整"><a href="#2-项目目录说明调整" class="headerlink" title="2. 项目目录说明调整"></a>2. 项目目录说明调整</h2><ul>
<li>目录说明</li>
</ul>
<ol>
<li><ol>
<li><code>src</code> 目录是我们写代码进行项目开发的目录</li>
<li><code>package.json</code>  中俩个核心库：react 、react-dom</li>
</ol>
</li>
</ol>
<ul>
<li>目录调整</li>
</ul>
<ol>
<li><ol>
<li>删除src目录下自带的所有文件，只保留app.js根组件和index.js</li>
<li>创建index.js文件作为项目的入口文件，在这个文件中书写react代码即可</li>
</ol>
</li>
</ol>
<ul>
<li>入口文件说明</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">ReactDOM</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-dom&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-string">&#x27;./index.css&#x27;</span><br><span class="hljs-comment">// 引入根组件App</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./App&#x27;</span><br><span class="hljs-comment">// 通过调用ReactDOM的render方法渲染App根组件到id为root的dom节点上</span><br><span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span><br><span class="language-xml">  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>,<br>  <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>)<br>)<br></code></pre></td></tr></table></figure>

<h1 id="JSX基础"><a href="#JSX基础" class="headerlink" title="JSX基础"></a>JSX基础</h1><h2 id="1-JSX介绍"><a href="#1-JSX介绍" class="headerlink" title="1. JSX介绍"></a>1. JSX介绍</h2><p><code>目标任务:</code>  能够理解什么是JSX，JSX的底层是什么</p>
<p>概念：JSX是 JavaScript XML（HTML）的缩写，表示在 JS 代码中书写 HTML 结构</p>
<p>作用：在React中创建HTML结构（页面UI结构）</p>
<p>优势：</p>
<ol>
<li>采用类似于HTML的语法，降低学习成本，会HTML就会JSX</li>
<li>充分利用JS自身的可编程能力创建HTML结构</li>
</ol>
<p>注意：JSX 并不是标准的 JS 语法，是 JS 的语法扩展，浏览器默认是不识别的，脚手架中内置的 <a href="@babel/plugin-transform-react-jsx">@babel&#x2F;plugin-transform-react-jsx</a> 包，用来解析该语法</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132132145.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<h2 id="2-JSX中使用js表达式"><a href="#2-JSX中使用js表达式" class="headerlink" title="2. JSX中使用js表达式"></a>2. JSX中使用js表达式</h2><p><code>目标任务:</code>  能够在JSX中使用表达式</p>
<p><strong>语法</strong></p>
<figure class="highlight xquery"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs xquery">&#123; JS 表达式 &#125;<br>const<span class="hljs-built_in"> name</span> = <span class="hljs-string">&#x27;柴柴&#x27;</span><br><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>你好，我叫</span><span class="language-xquery"><span class="hljs-built_in">&#123;name</span>&#125;</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>   //    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>你好,我叫柴柴<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span><br></code></pre></td></tr></table></figure>



<p><strong>可以使用的表达式</strong></p>
<ol>
<li>字符串、数值、布尔值、null、undefined、object（ [] &#x2F; {} ）</li>
<li>1 + 2、’abc’.split(‘’)、[‘a’, ‘b’].join(‘-‘)</li>
<li>fn()</li>
</ol>
<p><strong>特别注意</strong></p>
<p>if 语句&#x2F; switch-case 语句&#x2F; 变量声明语句，这些叫做语句，不是表达式，不能出现在 <code>&#123;&#125;</code> 中！！</p>
<h2 id="3-JSX列表渲染"><a href="#3-JSX列表渲染" class="headerlink" title="3. JSX列表渲染"></a>3. JSX列表渲染</h2><p><code>目标任务:</code>  能够在JSX中实现列表渲染</p>
<p>页面的构建离不开重复的列表结构，比如歌曲列表，商品列表等，我们知道vue中用的是v-for，react这边如何实现呢？</p>
<p>实现：使用数组的<code>map</code> 方法</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 来个列表</span><br><span class="hljs-keyword">const</span> songs = [<br>  &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;痴心绝对&#x27;</span> &#125;,<br>  &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;像我这样的人&#x27;</span> &#125;,<br>  &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;南山南&#x27;</span> &#125;<br>]<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">        &#123;</span><br><span class="language-xml">          songs.map(item =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>&#123;item.name&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>)</span><br><span class="language-xml">        &#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<p>注意点：需要为遍历项添加 <code>key</code> 属性</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133365.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<ol>
<li>key 在 HTML 结构中是看不到的，是 React 内部用来进行性能优化时使用</li>
<li>key 在当前列表中要唯一的字符串或者数值（String&#x2F;Number）</li>
<li>如果列表中有像 id 这种的唯一值，就用 id 来作为 key 值</li>
<li>如果列表中没有像 id 这种的唯一值，就可以使用 index（下标）来作为 key 值</li>
</ol>
<h2 id="4-JSX条件渲染"><a href="#4-JSX条件渲染" class="headerlink" title="4. JSX条件渲染"></a>4. JSX条件渲染</h2><p><code>目标任务:</code>  能够在JSX中实现条件渲染</p>
<p>作用：根据是否满足条件生成HTML结构，比如Loading效果</p>
<p>实现：可以使用 <code>三元运算符</code> 或  <code>逻辑与(&amp;&amp;)运算符</code></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 来个布尔值</span><br><span class="hljs-keyword">const</span> flag = <span class="hljs-literal">true</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      &#123;/* 条件渲染字符串 */&#125;</span><br><span class="language-xml">      &#123;flag ? &#x27;react真有趣&#x27; : &#x27;vue真有趣&#x27;&#125;</span><br><span class="language-xml">      &#123;/* 条件渲染标签/组件 */&#125;</span><br><span class="language-xml">      &#123;flag ? <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>this is span<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> : null&#125;</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="5-JSX样式处理"><a href="#5-JSX样式处理" class="headerlink" title="5. JSX样式处理"></a>5. JSX样式处理</h2><p><code>目标任务:</code>  能够在JSX中实现css样式处理</p>
<ul>
<li>行内样式 - style</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&#123;&#123;</span> <span class="hljs-attr">color:</span> &#x27;<span class="hljs-attr">red</span>&#x27; &#125;&#125;&gt;</span>this is a div<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<ul>
<li>行内样式 - style - 更优写法</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">const</span> styleObj = &#123;<br>    <span class="hljs-attr">color</span>:red<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&#123;</span> <span class="hljs-attr">styleObj</span> &#125;&gt;</span>this is a div<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<ul>
<li>类名 - className（推荐）</li>
</ul>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-class">.title</span> &#123;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">30px</span>;<br>  <span class="hljs-attribute">color</span>: blue;<br>&#125;<br></code></pre></td></tr></table></figure>



<ul>
<li>类名 - className - 动态类名控制</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-string">&#x27;./app.css&#x27;</span><br><span class="hljs-keyword">const</span> showTitle = <span class="hljs-literal">true</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&#123;</span> <span class="hljs-attr">showTitle</span> ? &#x27;<span class="hljs-attr">title</span>&#x27; <span class="hljs-attr">:</span> &#x27;&#x27;&#125;&gt;</span>this is a div<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<h2 id="6-JSX注意事项"><a href="#6-JSX注意事项" class="headerlink" title="6. JSX注意事项"></a>6. JSX注意事项</h2><p><code>目标任务:</code>  掌握JSX在实际应用时的注意事项</p>
<ol>
<li>JSX必须有一个根节点，如果没有根节点，可以使用<code>&lt;&gt;&lt;/&gt;</code>（幽灵节点）替代</li>
<li>所有标签必须形成闭合，成对闭合或者自闭合都可以</li>
<li>JSX中的语法更加贴近JS语法，属性名采用驼峰命名法  <code>class -&gt; className</code>  <code>for -&gt; htmlFor</code></li>
<li>JSX支持多行（换行），如果需要换行，需使用<code>()</code> 包裹，防止bug出现</li>
</ol>
<h2 id="格式化配置"><a href="#格式化配置" class="headerlink" title="格式化配置"></a>格式化配置</h2><p><code>目标任务:</code>  基于vscode配置格式化工具，提高开发效率</p>
<ol>
<li>安装vsCode prettier插件 </li>
<li>修改配置文件 <code>setting.json</code></li>
</ol>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;git.enableSmartCommit&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// 修改注释颜色</span><br>  <span class="hljs-attr">&quot;editor.tokenColorCustomizations&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;comments&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>      <span class="hljs-attr">&quot;fontStyle&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;bold&quot;</span><span class="hljs-punctuation">,</span><br>      <span class="hljs-attr">&quot;foreground&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;#82e0aa&quot;</span><br>    <span class="hljs-punctuation">&#125;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// 配置文件类型识别</span><br>  <span class="hljs-attr">&quot;files.associations&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;*.js&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;javascript&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;*.json&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jsonc&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;*.cjson&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;jsonc&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;*.wxss&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;css&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;*.wxs&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;javascript&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;extensions.ignoreRecommendations&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;files.exclude&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;**/.DS_Store&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;**/.git&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;**/.hg&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;**/.svn&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;**/CVS&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;**/node_modules&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;**/tmp&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// &quot;javascript.implicitProjectConfig.experimentalDecorators&quot;: true,</span><br>  <span class="hljs-attr">&quot;explorer.confirmDragAndDrop&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;typescript.updateImportsOnFileMove.enabled&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;prompt&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;git.confirmSync&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;editor.tabSize&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">2</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;editor.fontWeight&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;500&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;[json]&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;editor.tabCompletion&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;on&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;vsicons.projectDetection.autoReload&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;editor.fontFamily&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;Monaco, &#x27;Courier New&#x27;, monospace, Meslo LG M for Powerline&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;[html]&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;editor.defaultFormatter&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;vscode.html-language-features&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;editor.fontSize&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">16</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;debug.console.fontSize&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">14</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;vsicons.dontShowNewVersionMessage&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;editor.minimap.enabled&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;emmet.extensionsPath&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><br>    <span class="hljs-string">&quot;&quot;</span><br>  <span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// vue eslint start 保存时自动格式化代码</span><br>  <span class="hljs-attr">&quot;editor.formatOnSave&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// eslint配置项，保存时自动修复错误</span><br>  <span class="hljs-attr">&quot;editor.codeActionsOnSave&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;source.fixAll&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;vetur.ignoreProjectWarning&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// 让vetur使用vs自带的js格式化工具</span><br>  <span class="hljs-comment">// uni-app和vue 项目使用</span><br>  <span class="hljs-attr">&quot;vetur.format.defaultFormatter.js&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;vscode-typescript&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;javascript.format.semicolons&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;remove&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// // 指定 *.vue 文件的格式化工具为vetur</span><br>  <span class="hljs-attr">&quot;[vue]&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;editor.defaultFormatter&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;octref.vetur&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// // 指定 *.js 文件的格式化工具为vscode自带</span><br>  <span class="hljs-attr">&quot;[javascript]&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;editor.defaultFormatter&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;vscode.typescript-language-features&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// // 默认使用prettier格式化支持的文件</span><br>  <span class="hljs-attr">&quot;editor.defaultFormatter&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;esbenp.prettier-vscode&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;prettier.jsxBracketSameLine&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// 函数前面加个空格</span><br>  <span class="hljs-attr">&quot;javascript.format.insertSpaceBeforeFunctionParenthesis&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;prettier.singleQuote&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;prettier.semi&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// eslint end</span><br>  <span class="hljs-comment">// react</span><br>  <span class="hljs-comment">// 当按tab键的时候，会自动提示</span><br>  <span class="hljs-attr">&quot;emmet.triggerExpansionOnTab&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;emmet.showAbbreviationSuggestions&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;emmet.includeLanguages&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-comment">// jsx的提示</span><br>    <span class="hljs-attr">&quot;javascript&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;javascriptreact&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;vue-html&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;html&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;vue&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;html&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;wxml&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;html&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// end</span><br>  <span class="hljs-attr">&quot;[jsonc]&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;editor.defaultFormatter&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;vscode.json-language-features&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-comment">// @路径提示</span><br>  <span class="hljs-attr">&quot;path-intellisense.mappings&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;@&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;$&#123;workspaceRoot&#125;/src&quot;</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;security.workspace.trust.untrustedFiles&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;open&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;git.ignoreMissingGitWarning&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;window.zoomLevel&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">1</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure>

<h2 id="阶段小练习"><a href="#阶段小练习" class="headerlink" title="阶段小练习"></a>阶段小练习</h2><p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133601.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p>练习说明</p>
<ol>
<li>拉取准备好的项目模块到本地 ，安装依赖，run起来项目<br>   <a target="_blank" rel="noopener" href="https://gitee.com/react-course-series/react-jsx-demo">https://gitee.com/react-course-series/react-jsx-demo</a> </li>
<li>按照图示，完成 <code>评论数据渲染</code>  <code>tab内容渲染</code>  <code>评论列表点赞和点踩</code>  三个视图渲染</li>
</ol>
<h1 id="React组件基础"><a href="#React组件基础" class="headerlink" title="React组件基础"></a>React组件基础</h1><h2 id="组件概念"><a href="#组件概念" class="headerlink" title="组件概念"></a>组件概念</h2><p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133194.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<h2 id="函数组件"><a href="#函数组件" class="headerlink" title="函数组件"></a>函数组件</h2><p><code>目标任务:</code>  能够独立使用函数完成react组件的创建和渲染</p>
<p><strong>概念</strong></p>
<p>使用 JS 的函数（或箭头函数）创建的组件，就叫做<code>函数组件</code></p>
<p><strong>组件定义与渲染</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 定义函数组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">HelloFn</span> () &#123;<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>这是我的第一个函数组件!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&#125;<br><br><span class="hljs-comment">// 定义类组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span> () &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      &#123;/* 渲染函数组件 */&#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">HelloFn</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">HelloFn</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">HelloFn</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<p><strong>约定说明</strong></p>
<ol>
<li>组件的名称<strong>必须首字母大写</strong>，react内部会根据这个来判断是组件还是普通的HTML标签</li>
<li>函数组件<strong>必须有返回值</strong>，表示该组件的 UI 结构；如果不需要渲染任何内容，则返回 null</li>
<li>组件就像 HTML 标签一样可以被渲染到页面中。组件表示的是一段结构内容，对于函数组件来说，渲染的内容是函数的<strong>返回值</strong>就是对应的内容</li>
<li>使用函数名称作为组件标签名称，可以成对出现也可以自闭合</li>
</ol>
<h2 id="类组件"><a href="#类组件" class="headerlink" title="类组件"></a>类组件</h2><p><code>目标任务:</code>  能够独立完成类组件的创建和渲染</p>
<p>使用 ES6 的 class 创建的组件，叫做类（class）组件</p>
<p><strong>组件定义与渲染</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 引入React</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 定义类组件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">HelloC</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  render () &#123;<br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>这是我的第一个类组件!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span> () &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      &#123;/* 渲染类组件 */&#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">HelloC</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">HelloC</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">HelloC</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<p><strong>约定说明</strong></p>
<ol>
<li><strong>类名称也必须以大写字母开头</strong></li>
<li>类组件应该继承 React.Component 父类，从而使用父类中提供的方法或属性</li>
<li>类组件必须提供 render 方法<strong>render 方法必须有返回值，表示该组件的 UI 结构</strong></li>
</ol>
<h2 id="函数组件的事件绑定"><a href="#函数组件的事件绑定" class="headerlink" title="函数组件的事件绑定"></a>函数组件的事件绑定</h2><p><code>目标任务:</code>  能够独立绑定任何事件并能获取到事件对象e</p>
<h3 id="1-如何绑定事件"><a href="#1-如何绑定事件" class="headerlink" title="1. 如何绑定事件"></a>1. 如何绑定事件</h3><ul>
<li>语法<br>  on + 事件名称 &#x3D; { 事件处理程序 } ，比如：<code>&lt;div onClick=&#123; onClick &#125;&gt;&lt;/div&gt;</code> </li>
<li>注意点<br>  react事件采用驼峰命名法，比如：onMouseEnter、onFocus </li>
<li>样例</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 函数组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">HelloFn</span> () &#123;<br>  <span class="hljs-comment">// 定义事件回调函数</span><br>  <span class="hljs-keyword">const</span> <span class="hljs-title function_">clickHandler</span> = (<span class="hljs-params"></span>) =&gt; &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;事件被触发了&#x27;</span>)<br>  &#125;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="hljs-comment">// 绑定事件</span><br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;clickHandler&#125;</span>&gt;</span>click me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="2-获取事件对象"><a href="#2-获取事件对象" class="headerlink" title="2. 获取事件对象"></a>2. 获取事件对象</h3><p> 获取事件对象e只需要在 事件的回调函数中 补充一个形参e即可拿到</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 函数组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">HelloFn</span> () &#123;<br>  <span class="hljs-comment">// 定义事件回调函数</span><br>  <span class="hljs-keyword">const</span> <span class="hljs-title function_">clickHandler</span> = (<span class="hljs-params">e</span>) =&gt; &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;事件被触发了&#x27;</span>, e)<br>  &#125;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="hljs-comment">// 绑定事件</span><br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;clickHandler&#125;</span>&gt;</span>click me!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="3-传递额外参数"><a href="#3-传递额外参数" class="headerlink" title="3. 传递额外参数"></a>3. 传递额外参数</h3><p>解决思路: 改造事件绑定为箭头函数 在箭头函数中完成参数的传递</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;react&quot;</span><br><br><span class="hljs-comment">// 如何获取额外的参数？</span><br><span class="hljs-comment">// onClick=&#123; onDel &#125; -&gt; onClick=&#123; () =&gt; onDel(id) &#125;</span><br><span class="hljs-comment">// 注意: 一定不要在模板中写出函数调用的代码 onClick = &#123; onDel(id) &#125;  bad!!!!!!</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">TestComponent</span> = (<span class="hljs-params"></span>) =&gt; &#123;<br>  <span class="hljs-keyword">const</span> list = [<br>    &#123;<br>      <span class="hljs-attr">id</span>: <span class="hljs-number">1001</span>,<br>      <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;react&#x27;</span><br>    &#125;,<br>    &#123;<br>      <span class="hljs-attr">id</span>: <span class="hljs-number">1002</span>,<br>      <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;vue&#x27;</span><br>    &#125;<br>  ]<br>  <span class="hljs-keyword">const</span> <span class="hljs-title function_">onDel</span> = (<span class="hljs-params">e, id</span>) =&gt; &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(e, id)<br>  &#125;<br>  <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">        &#123;list.map(item =&gt;（</span><br><span class="language-xml">           <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;item.id&#125;</span>&gt;</span></span><br><span class="language-xml">                &#123;item.name&#125;</span><br><span class="language-xml">                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;(e)</span> =&gt;</span> onDel(e, item.id)&#125;&gt;x<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">           <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">        ))&#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span> () &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">TestComponent</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<h2 id="类组件的事件绑定"><a href="#类组件的事件绑定" class="headerlink" title="类组件的事件绑定"></a>类组件的事件绑定</h2><p>类组件中的事件绑定，整体的方式和函数组件差别不大</p>
<p>唯一需要注意的 因为处于class类语境下 所以定义事件回调函数以及定它写法上有不同</p>
<ol>
<li>定义的时候: class Fields语法</li>
</ol>
<p>  \2. 使用的时候: 需要借助this关键词获取</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;react&quot;</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">// class Fields</span><br>  clickHandler = <span class="hljs-function">(<span class="hljs-params">e, num</span>) =&gt;</span> &#123;<br>    <span class="hljs-comment">// 这里的this指向的是正确的当前的组件实例对象 </span><br>    <span class="hljs-comment">// 可以非常方便的通过this关键词拿到组件实例身上的其他属性或者方法</span><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>)<br>  &#125;<br><br>  clickHandler1 () &#123;<br>    <span class="hljs-comment">// 这里的this 不指向当前的组件实例对象而指向undefined 存在this丢失问题</span><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>)<br>  &#125;<br><br>  render () &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;(e)</span> =&gt;</span> this.clickHandler(e, &#x27;123&#x27;)&#125;&gt;click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.clickHandler1&#125;</span>&gt;</span>click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span> () &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">CComponent</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<h2 id="组件状态"><a href="#组件状态" class="headerlink" title="组件状态"></a>组件状态</h2><p><code>目标任务:</code>  能够为组件添加状态和修改状态的值</p>
<p>一个前提：在React hook出来之前，函数式组件是没有自己的状态的，所以我们统一通过类组件来讲解</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133508.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<h3 id="1-初始化状态"><a href="#1-初始化状态" class="headerlink" title="1. 初始化状态"></a>1. 初始化状态</h3><ul>
<li>通过class的实例属性state来初始化 </li>
<li>state的值是一个对象结构，表示一个组件可以有多个数据状态</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">// 初始化状态</span><br>  state = &#123;<br>    <span class="hljs-attr">count</span>: <span class="hljs-number">0</span><br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>计数器<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="2-读取状态"><a href="#2-读取状态" class="headerlink" title="2. 读取状态"></a>2. 读取状态</h3><ul>
<li>通过this.state来获取状态</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">// 初始化状态</span><br>  state = &#123;<br>    <span class="hljs-attr">count</span>: <span class="hljs-number">0</span><br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 读取状态</span><br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>计数器&#123;this.state.count&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="3-修改状态"><a href="#3-修改状态" class="headerlink" title="3. 修改状态"></a>3. 修改状态</h3><ul>
<li>语法<br>  <code>this.setState(&#123; 要修改的部分数据 &#125;)</code> </li>
<li>setState方法作用</li>
</ul>
<ol>
<li><ol>
<li>修改state中的数据状态</li>
<li>更新UI</li>
</ol>
</li>
</ol>
<ul>
<li>思想<br> 数据驱动视图，也就是只要修改数据状态，那么页面就会自动刷新，无需手动操作dom </li>
<li>注意事项<br> <strong>不要直接修改state中的值，必须通过setState方法进行修改</strong></li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">// 定义数据</span><br>  state = &#123;<br>    <span class="hljs-attr">count</span>: <span class="hljs-number">0</span><br>  &#125;<br>  <span class="hljs-comment">// 定义修改数据的方法</span><br>  setCount = <span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">count</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">count</span> + <span class="hljs-number">1</span><br>    &#125;)<br>  &#125;<br>  <span class="hljs-comment">// 使用数据 并绑定事件</span><br>  render () &#123;<br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.setCount&#125;</span>&gt;</span>&#123;this.state.count&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>



<h2 id="this问题说明"><a href="#this问题说明" class="headerlink" title="this问题说明"></a>this问题说明</h2><p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133120.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p>这里我们作为了解内容，随着js标准的发展，主流的写法已经变成了class fields，无需考虑太多this问题</p>
<h2 id="React的状态不可变"><a href="#React的状态不可变" class="headerlink" title="React的状态不可变"></a>React的状态不可变</h2><p><code>目标任务:</code>  能够理解不可变的意义并且知道在实际开发中如何修改状态</p>
<p><strong>概念</strong>：不要直接修改状态的值，而是基于当前状态创建新的状态值</p>
<p><strong>1. 错误的直接修改</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs javascript">state = &#123;<br>  count : <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">list</span>: [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>],<br>  <span class="hljs-attr">person</span>: &#123;<br>     <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;jack&#x27;</span>,<br>     <span class="hljs-attr">age</span>:<span class="hljs-number">18</span><br>  &#125;<br>&#125;<br><span class="hljs-comment">// 直接修改简单类型Number</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">count</span>++<br>++<span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">count</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">count</span> += <span class="hljs-number">1</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">count</span> = <span class="hljs-number">1</span><br><br><span class="hljs-comment">// 直接修改数组</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">list</span>.<span class="hljs-title function_">push</span>(<span class="hljs-number">123</span>)<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">list</span>.<span class="hljs-title function_">spice</span>(<span class="hljs-number">1</span>,<span class="hljs-number">1</span>)<br><br><span class="hljs-comment">// 直接修改对象</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">person</span>.<span class="hljs-property">name</span> = <span class="hljs-string">&#x27;rose&#x27;</span><br></code></pre></td></tr></table></figure>



<p><strong>2. 基于当前状态创建新值</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>    <span class="hljs-attr">count</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">count</span> + <span class="hljs-number">1</span><br>    <span class="hljs-attr">list</span>: [...<span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">list</span>, <span class="hljs-number">4</span>],<br>    <span class="hljs-attr">person</span>: &#123;<br>       ...<span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">person</span>,<br>       <span class="hljs-comment">// 覆盖原来的属性 就可以达到修改对象中属性的目的</span><br>       <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;rose&#x27;</span><br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

<h2 id="表单处理"><a href="#表单处理" class="headerlink" title="表单处理"></a>表单处理</h2><p><code>目标任务:</code>  能够使用受控组件的方式获取文本框的值</p>
<p>使用React处理表单元素，一般有俩种方式：</p>
<ol>
<li>受控组件 （推荐使用）</li>
<li>非受控组件 （了解）</li>
</ol>
<h3 id="1-受控表单组件"><a href="#1-受控表单组件" class="headerlink" title="1. 受控表单组件"></a>1. 受控表单组件</h3><p>什么是受控组件？  <code>input框自己的状态被React组件状态控制</code></p>
<p>React组件的状态的地方是在state中，input表单元素也有自己的状态是在value中，React将state与表单元素的值（value）绑定到一起，由state的值来控制表单元素的值，从而保证单一数据源特性</p>
<p><strong>实现步骤</strong></p>
<p>以获取文本框的值为例，受控组件的使用步骤如下：</p>
<ol>
<li>在组件的state中声明一个组件的状态数据</li>
<li>将状态数据设置为input标签元素的value属性的值</li>
<li>为input添加change事件，在事件处理程序中，通过事件对象e获取到当前文本框的值（<code>即用户当前输入的值</code>）</li>
<li>调用setState方法，将文本框的值作为state状态的最新值</li>
</ol>
<p><strong>代码落地</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">InputComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">// 声明组件状态</span><br>  state = &#123;<br>    <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;this is message&#x27;</span>,<br>  &#125;<br>  <span class="hljs-comment">// 声明事件回调函数</span><br>  changeHandler = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123; <span class="hljs-attr">message</span>: e.<span class="hljs-property">target</span>.<span class="hljs-property">value</span> &#125;)<br>  &#125;<br>  render () &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        &#123;/* 绑定value 绑定事件*/&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&#123;this.state.message&#125;</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">&#123;this.changeHandler&#125;</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span> () &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">InputComponent</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h3 id="2-非受控表单组件"><a href="#2-非受控表单组件" class="headerlink" title="2. 非受控表单组件"></a>2. 非受控表单组件</h3><p>什么是非受控组件？</p>
<p>非受控组件就是通过手动操作dom的方式获取文本框的值，文本框的状态不受react组件的state中的状态控制，直接通过原生dom获取输入框的值</p>
<p><strong>实现步骤</strong></p>
<ol>
<li>导入<code>createRef</code> 函数</li>
<li>调用createRef函数，创建一个ref对象，存储到名为<code>msgRef</code>的实例属性中</li>
<li>为input添加ref属性，值为<code>msgRef</code></li>
<li>在按钮的事件处理程序中，通过<code>msgRef.current</code>即可拿到input对应的dom元素，而其中<code>msgRef.current.value</code>拿到的就是文本框的值</li>
</ol>
<p><strong>代码落地</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; createRef &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">InputComponent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">// 使用createRef产生一个存放dom的对象容器</span><br>  msgRef = <span class="hljs-title function_">createRef</span>()<br><br>  changeHandler = <span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">msgRef</span>.<span class="hljs-property">current</span>.<span class="hljs-property">value</span>)<br>  &#125;<br><br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        &#123;/* ref绑定 获取真实dom */&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&#123;this.msgRef&#125;</span> /&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.changeHandler&#125;</span>&gt;</span>click<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span> () &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;App&quot;</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">InputComponent</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="阶段小练习-1"><a href="#阶段小练习-1" class="headerlink" title="阶段小练习"></a>阶段小练习</h2><p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133195.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p><strong>练习说明</strong></p>
<ol>
<li>拉取项目模板到本地，安装依赖，run起来项目<br>   <a target="_blank" rel="noopener" href="https://gitee.com/react-course-series/react-component-demo">https://gitee.com/react-course-series/react-component-demo</a> </li>
<li>完成tab点击切换激活状态交互 </li>
<li>完成发表评论功能<br>   注意：生成独立无二的id 可以使用  uuid 包  <code>yarn add uuid</code></li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> &#123; v4 <span class="hljs-keyword">as</span> uuid &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;uuid&#x27;</span><br><span class="hljs-title function_">uuid</span>() <span class="hljs-comment">// 得到一个独一无二的id</span><br></code></pre></td></tr></table></figure>

<ol>
<li>完成删除评论功能</li>
</ol>
<h1 id="React组件通信"><a href="#React组件通信" class="headerlink" title="React组件通信"></a>React组件通信</h1><h2 id="组件通信的意义"><a href="#组件通信的意义" class="headerlink" title="组件通信的意义"></a>组件通信的意义</h2><p><code>目标任务:</code>  了解为什么需要组件通信</p>
<p>组件是独立且封闭的单元，默认情况下组件<strong>只能使用自己的数据（state）</strong></p>
<p>组件化开发的过程中，完整的功能会拆分多个组件，在这个过程中不可避免的需要互相传递一些数据</p>
<p>为了能让各组件之间可以进行互相沟通，数据传递，这个过程就是组件通信</p>
<ol>
<li>父子关系 -  <strong>最重要的</strong></li>
<li>兄弟关系 -  自定义事件模式产生技术方法 eventBus  &#x2F;  通过共同的父组件通信</li>
<li>其它关系 -  <strong>mobx &#x2F; redux &#x2F; zustand</strong></li>
</ol>
<h2 id="父传子实现"><a href="#父传子实现" class="headerlink" title="父传子实现"></a>父传子实现</h2><p><code>目标任务:</code>  实现父子通信中的父传子，把父组件中的数据传给子组件</p>
<p><strong>实现步骤</strong></p>
<ol>
<li><p>父组件提供要传递的数据  -  <code>state</code> </p>
</li>
<li><p>给子组件标签<code>添加属性</code>值为 state中的数据 </p>
</li>
<li><p>子组件中通过 <code>props</code> 接收父组件中传过来的数据 </p>
</li>
<li><ol>
<li>类组件使用this.props获取props对象</li>
<li>函数式组件直接通过参数获取props对象</li>
</ol>
</li>
</ol>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133457.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p><strong>代码实现</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 函数式子组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">FSon</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(props)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      子组件1</span><br><span class="language-xml">      &#123;props.msg&#125;</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// 类子组件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CSon</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        子组件2</span><br><span class="language-xml">        &#123;this.props.msg&#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;this is message&#x27;</span><br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>父组件<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">FSon</span> <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;this.state.message&#125;</span> /&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">CSon</span> <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;this.state.message&#125;</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="props说明"><a href="#props说明" class="headerlink" title="props说明"></a>props说明</h2><p><code>目标任务:</code>  知道props传递时的一些注意事项</p>
<p><strong>1.  props是只读对象（readonly）</strong></p>
<p>根据单项数据流的要求，子组件只能读取props中的数据，不能进行修改</p>
<p><strong>2. props可以传递任意数据</strong></p>
<p>数字、字符串、布尔值、数组、对象、<code>函数、JSX</code></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;this is message&#x27;</span><br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>父组件<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">FSon</span> </span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;this.state.message&#125;</span> </span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">age</span>=<span class="hljs-string">&#123;20&#125;</span> </span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">isMan</span>=<span class="hljs-string">&#123;true&#125;</span> </span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">cb</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> &#123; console.log(1) &#125;&#125; </span><br><span class="language-xml">          child=&#123;<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>this is child<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>&#125;</span><br><span class="language-xml">        /&gt;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">CSon</span> <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;this.state.message&#125;</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>



<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132133896.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<h2 id="子传父实现"><a href="#子传父实现" class="headerlink" title="子传父实现"></a>子传父实现</h2><p><code>目标任务:</code>  实现父子通信中的子传父</p>
<p><strong>口诀：</strong> 父组件给子组件传递回调函数，子组件调用</p>
<p><strong>实现步骤</strong></p>
<ol>
<li>父组件提供一个回调函数 - 用于接收数据</li>
<li>将函数作为属性的值，传给子组件</li>
<li>子组件通过props调用 回调函数</li>
<li>将子组件中的数据作为参数传递给回调函数</li>
</ol>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134113.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p><strong>代码实现</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Son</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">function</span> <span class="hljs-title function_">handleClick</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 调用父组件传递过来的回调函数 并注入参数</span><br>    props.<span class="hljs-title function_">changeMsg</span>(<span class="hljs-string">&#x27;this is newMessage&#x27;</span>)<br>  &#125;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      &#123;props.msg&#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;handleClick&#125;</span>&gt;</span>change<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;this is message&#x27;</span><br>  &#125;<br>  <span class="hljs-comment">// 提供回调函数</span><br>  changeMessage = <span class="hljs-function">(<span class="hljs-params">newMsg</span>) =&gt;</span> &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;子组件传过来的数据:&#x27;</span>,newMsg)<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">message</span>: newMsg<br>    &#125;)<br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>父组件<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">Son</span></span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;this.state.message&#125;</span></span></span><br><span class="hljs-tag"><span class="language-xml">          // <span class="hljs-attr">传递给子组件</span></span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">changeMsg</span>=<span class="hljs-string">&#123;this.changeMessage&#125;</span></span></span><br><span class="hljs-tag"><span class="language-xml">        /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="兄弟组件通信"><a href="#兄弟组件通信" class="headerlink" title="兄弟组件通信"></a>兄弟组件通信</h2><p><code>目标任务:</code>  实现兄弟组件之间的通信</p>
<p><strong>核心思路：</strong> 通过状态提升机制，利用共同的父组件实现兄弟通信</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134670.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p><strong>实现步骤</strong></p>
<ol>
<li>将共享状态提升到最近的公共父组件中，由公共父组件管理这个状态</li>
</ol>
<ul>
<li><ul>
<li>提供共享状态</li>
<li>提供操作共享状态的方法</li>
</ul>
</li>
</ul>
<ol>
<li>要接收数据状态的子组件通过 props 接收数据</li>
<li>要传递数据状态的子组件通过props接收方法，调用方法传递数据</li>
</ol>
<p><strong>代码实现</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 子组件A</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">SonA</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      SonA</span><br><span class="language-xml">      &#123;props.msg&#125;</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-comment">// 子组件B</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">SonB</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      SonB</span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> props.changeMsg(&#x27;new message&#x27;)&#125;&gt;changeMsg<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">// 父组件提供状态数据</span><br>  state = &#123;<br>    <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;this is message&#x27;</span><br>  &#125;<br>  <span class="hljs-comment">// 父组件提供修改数据的方法</span><br>  changeMsg = <span class="hljs-function">(<span class="hljs-params">newMsg</span>) =&gt;</span> &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">message</span>: newMsg<br>    &#125;)<br>  &#125;<br><br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">        &#123;/* 接收数据的组件 */&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">SonA</span> <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;this.state.message&#125;</span> /&gt;</span></span><br><span class="language-xml">        &#123;/* 修改数据的组件 */&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">SonB</span> <span class="hljs-attr">changeMsg</span>=<span class="hljs-string">&#123;this.changeMsg&#125;</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="跨组件通信Context"><a href="#跨组件通信Context" class="headerlink" title="跨组件通信Context"></a>跨组件通信Context</h2><p><code>目标任务:</code>  了解Context机制解决的问题和使用步骤</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134015.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p>上图是一个react形成的嵌套组件树，如果我们想从App组件向任意一个下层组件传递数据，该怎么办呢？目前我们能采取的方式就是一层一层的props往下传，显然很繁琐</p>
<p>那么，Context 提供了一个<strong>无需为每层组件手动添加 props，就能在组件树间进行数据传递的方法</strong></p>
<p><strong>实现步骤</strong></p>
<p>1- 创建Context对象 导出 Provider 和 Consumer对象 </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> &#123; <span class="hljs-title class_">Provider</span>, <span class="hljs-title class_">Consumer</span> &#125; = <span class="hljs-title function_">createContext</span>()<br></code></pre></td></tr></table></figure>

<p>2- 使用Provider包裹上层组件提供数据 </p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx">&lt;<span class="hljs-title class_">Provider</span> value=&#123;<span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">message</span>&#125;&gt;<br>    &#123;<span class="hljs-comment">/* 根组件 */</span>&#125;<br>&lt;/<span class="hljs-title class_">Provider</span>&gt;<br></code></pre></td></tr></table></figure>

<p>3- 需要用到数据的组件使用Consumer包裹获取数据 </p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx">&lt;<span class="hljs-title class_">Consumer</span> &gt;<br>    &#123;<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> <span class="hljs-comment">/* 基于 context 值进行渲染*/</span>&#125;<br>&lt;/<span class="hljs-title class_">Consumer</span>&gt;<br></code></pre></td></tr></table></figure>

<p><strong>代码实现</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; createContext &#125;  <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 1. 创建Context对象 </span><br><span class="hljs-keyword">const</span> &#123; <span class="hljs-title class_">Provider</span>, <span class="hljs-title class_">Consumer</span> &#125; = <span class="hljs-title function_">createContext</span>()<br><br><br><span class="hljs-comment">// 3. 消费数据</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">ComC</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Consumer</span> &gt;</span></span><br><span class="language-xml">      &#123;value =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>&#123;value&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>&#125;</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">Consumer</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">ComA</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ComC</span>/&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// 2. 提供数据</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;this is message&#x27;</span><br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&#123;this.state.message&#125;</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;app&quot;</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">ComA</span> /&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="阶段小练习-2"><a href="#阶段小练习-2" class="headerlink" title="阶段小练习"></a>阶段小练习</h2><p>要求：App为父组件用来提供列表数据 ，ListItem为子组件用来渲染列表数据</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134395.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 列表数据</span><br>[<br>  &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;超级好吃的棒棒糖&#x27;</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">18.8</span>, <span class="hljs-attr">info</span>: <span class="hljs-string">&#x27;开业大酬宾，全场8折&#x27;</span> &#125;,<br>  &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;超级好吃的大鸡腿&#x27;</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">34.2</span>, <span class="hljs-attr">info</span>: <span class="hljs-string">&#x27;开业大酬宾，全场8折&#x27;</span> &#125;,<br>  &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;超级无敌的冰激凌&#x27;</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">14.2</span>, <span class="hljs-attr">info</span>: <span class="hljs-string">&#x27;开业大酬宾，全场8折&#x27;</span> &#125;<br>]<br></code></pre></td></tr></table></figure>



<p>完整代码</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">ListItem</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">const</span> &#123; name, price, info, id, delHandler &#125; = props<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>&#123;name&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>&#123;price&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>&#123;info&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> delHandler(id)&#125;&gt;删除<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">list</span>: [<br>      &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;超级好吃的棒棒糖&#x27;</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">18.8</span>, <span class="hljs-attr">info</span>: <span class="hljs-string">&#x27;开业大酬宾，全场8折&#x27;</span> &#125;,<br>      &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;超级好吃的大鸡腿&#x27;</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">34.2</span>, <span class="hljs-attr">info</span>: <span class="hljs-string">&#x27;开业大酬宾，全场8折&#x27;</span> &#125;,<br>      &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;超级无敌的冰激凌&#x27;</span>, <span class="hljs-attr">price</span>: <span class="hljs-number">14.2</span>, <span class="hljs-attr">info</span>: <span class="hljs-string">&#x27;开业大酬宾，全场8折&#x27;</span> &#125;<br>    ]<br>  &#125;<br><br>  delHandler = <span class="hljs-function">(<span class="hljs-params">id</span>) =&gt;</span> &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">list</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">list</span>.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.<span class="hljs-property">id</span> !== id)<br>    &#125;)<br>  &#125;<br><br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">        &#123;</span><br><span class="language-xml">          this.state.list.map(item =&gt;</span><br><span class="language-xml">            <span class="hljs-tag">&lt;<span class="hljs-name">ListItem</span></span></span><br><span class="hljs-tag"><span class="language-xml">              <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;item.id&#125;</span></span></span><br><span class="hljs-tag"><span class="language-xml">              &#123;<span class="hljs-attr">...item</span>&#125;</span></span><br><span class="hljs-tag"><span class="language-xml">              <span class="hljs-attr">delHandler</span>=<span class="hljs-string">&#123;this.delHandler&#125;</span> </span></span><br><span class="hljs-tag"><span class="language-xml">            /&gt;</span></span><br><span class="language-xml">          )</span><br><span class="language-xml">        &#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;/&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h1 id="React组件进阶"><a href="#React组件进阶" class="headerlink" title="React组件进阶"></a>React组件进阶</h1><h2 id="children属性"><a href="#children属性" class="headerlink" title="children属性"></a>children属性</h2><p><code>目标任务:</code>  掌握props中children属性的用法</p>
<p><strong>children属性是什么</strong></p>
<p>表示该组件的子节点，只要组件内部有子节点，props中就有该属性</p>
<p><strong>children可以是什么</strong></p>
<ol>
<li>普通文本</li>
<li>普通标签元素</li>
<li>函数 &#x2F; 对象</li>
<li>JSX</li>
</ol>
<h2 id="props校验-场景和使用"><a href="#props校验-场景和使用" class="headerlink" title="props校验-场景和使用"></a>props校验-场景和使用</h2><p><code>目标任务:</code>  掌握组件props的校验写法，增加组件的健壮性</p>
<p>对于组件来说，props是由外部传入的，我们其实无法保证组件使用者传入了什么格式的数据，如果传入的数据格式不对，就有可能会导致组件内部错误，有一个点很关键 - <strong>组件的使用者可能报错了也不知道为什么</strong>，看下面的例子</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134115.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p>面对这样的问题，如何解决？ <strong>props校验</strong></p>
<p><strong>实现步骤</strong></p>
<ol>
<li>安装属性校验包：<code>yarn add prop-types</code></li>
<li>导入<code>prop-types</code> 包</li>
<li>使用 <code>组件名.propTypes = &#123;&#125;</code> 给组件添加校验规则</li>
</ol>
<p><strong>核心代码</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">PropTypes</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;prop-types&#x27;</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">List</span> = props =&gt; &#123;<br>  <span class="hljs-keyword">const</span> arr = props.<span class="hljs-property">colors</span><br>  <span class="hljs-keyword">const</span> lis = arr.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">item, index</span>) =&gt;</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;index&#125;</span>&gt;</span>&#123;item.name&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>)<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>&#123;lis&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br>&#125;<br><br><span class="hljs-title class_">List</span>.<span class="hljs-property">propTypes</span> = &#123;<br>  <span class="hljs-attr">colors</span>: <span class="hljs-title class_">PropTypes</span>.<span class="hljs-property">array</span><br>&#125;<br></code></pre></td></tr></table></figure>



<h2 id="props校验-规则说明"><a href="#props校验-规则说明" class="headerlink" title="props校验-规则说明"></a>props校验-规则说明</h2><p><code>目标任务:</code>  掌握props常见的规则</p>
<p><strong>四种常见结构</strong></p>
<ol>
<li>常见类型：array、bool、func、number、object、string</li>
<li>React元素类型：element</li>
<li>必填项：isRequired</li>
<li>特定的结构对象：shape({})</li>
</ol>
<p><strong>核心代码</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 常见类型</span><br><span class="hljs-attr">optionalFunc</span>: <span class="hljs-title class_">PropTypes</span>.<span class="hljs-property">func</span>,<br><span class="hljs-comment">// 必填 只需要在类型后面串联一个isRequired</span><br><span class="hljs-attr">requiredFunc</span>: <span class="hljs-title class_">PropTypes</span>.<span class="hljs-property">func</span>.<span class="hljs-property">isRequired</span>,<br><span class="hljs-comment">// 特定结构的对象</span><br><span class="hljs-attr">optionalObjectWithShape</span>: <span class="hljs-title class_">PropTypes</span>.<span class="hljs-title function_">shape</span>(&#123;<br>	<span class="hljs-attr">color</span>: <span class="hljs-title class_">PropTypes</span>.<span class="hljs-property">string</span>,<br>	<span class="hljs-attr">fontSize</span>: <span class="hljs-title class_">PropTypes</span>.<span class="hljs-property">number</span><br>&#125;)<br></code></pre></td></tr></table></figure>



<p>官网文档更多阅读：<a target="_blank" rel="noopener" href="https://reactjs.org/docs/typechecking-with-proptypes.html">https://reactjs.org/docs/typechecking-with-proptypes.html</a></p>
<h2 id="props校验-默认值"><a href="#props校验-默认值" class="headerlink" title="props校验-默认值"></a>props校验-默认值</h2><p><code>目标任务:</code>  掌握如何给组件的props提供默认值</p>
<p>通过 <code>defaultProps</code> 可以给组件的props设置默认值，在未传入props的时候生效</p>
<h3 id="1-函数组件"><a href="#1-函数组件" class="headerlink" title="1. 函数组件"></a>1. 函数组件</h3><p>直接使用函数参数默认值</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">function</span> <span class="hljs-title function_">List</span>(<span class="hljs-params">&#123;pageSize = <span class="hljs-number">10</span>&#125;</span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      此处展示props的默认值：&#123; pageSize &#125;</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// 不传入pageSize属性</span><br>&lt;<span class="hljs-title class_">List</span> /&gt;<br></code></pre></td></tr></table></figure>

<h3 id="2-类组件"><a href="#2-类组件" class="headerlink" title="2. 类组件"></a>2. 类组件</h3><p>使用类静态属性声明默认值，<code>static defaultProps = &#123;&#125;</code></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">class</span> <span class="hljs-title class_">List</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>  <span class="hljs-keyword">static</span> defaultProps = &#123;<br>    <span class="hljs-attr">pageSize</span>: <span class="hljs-number">10</span><br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        此处展示props的默认值：&#123;this.props.pageSize&#125;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br>&lt;<span class="hljs-title class_">List</span> /&gt;<br></code></pre></td></tr></table></figure>

<h2 id="生命周期-概述"><a href="#生命周期-概述" class="headerlink" title="生命周期 - 概述"></a>生命周期 - 概述</h2><p><code>目标任务:</code>  能够说出组件生命周期一共几个阶段</p>
<p>组件的生命周期是指组件从被创建到挂载到页面中运行起来，再到组件不用时卸载的过程，注意，只有类组件才有生命周期（类组件 实例化  函数组件 不需要实例化）</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134614.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<p><a target="_blank" rel="noopener" href="http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/">http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/</a></p>
<h2 id="生命周期-挂载阶段"><a href="#生命周期-挂载阶段" class="headerlink" title="生命周期 - 挂载阶段"></a>生命周期 - 挂载阶段</h2><p><code>目标任务:</code>  能够说出在组件挂载阶段执行的钩子函数和执行时机</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134723.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<table>
<thead>
<tr>
<th>钩子 函数</th>
<th>触发时机</th>
<th>作用</th>
</tr>
</thead>
<tbody><tr>
<td>constructor</td>
<td>创建组件时，最先执行，初始化的时候只执行一次</td>
<td>1. 初始化state  2. 创建 Ref 3. 使用 bind 解决 this 指向问题等</td>
</tr>
<tr>
<td>render</td>
<td>每次组件渲染都会触发</td>
<td>渲染UI（<strong>注意： 不能在里面调用setState()</strong> ）</td>
</tr>
<tr>
<td>componentDidMount</td>
<td>组件挂载（完成DOM渲染）后执行，初始化的时候执行一次</td>
<td>1. 发送网络请求  2.DOM操作</td>
</tr>
</tbody></table>
<h2 id="生命周期-更新阶段"><a href="#生命周期-更新阶段" class="headerlink" title="生命周期 - 更新阶段"></a>生命周期 - 更新阶段</h2><p><code>目标任务:</code>  能够说出组件的更新阶段的钩子函数以及执行时机</p>
<p><img src="https://gitee.com/tongstyle/blog-img/raw/master/img/202307132134129.png" srcset="/img/loading.gif" lazyload alt="img"></p>
<table>
<thead>
<tr>
<th>钩子函数</th>
<th>触发时机</th>
<th>作用</th>
</tr>
</thead>
<tbody><tr>
<td>render</td>
<td>每次组件渲染都会触发</td>
<td>渲染UI（与 挂载阶段 是同一个render）</td>
</tr>
<tr>
<td>componentDidUpdate</td>
<td>组件更新后（DOM渲染完毕）</td>
<td>DOM操作，可以获取到更新后的DOM内容，<strong>不要直接调用setState</strong></td>
</tr>
</tbody></table>
<h2 id="生命周期-卸载阶段"><a href="#生命周期-卸载阶段" class="headerlink" title="生命周期 - 卸载阶段"></a>生命周期 - 卸载阶段</h2><p><code>目标任务:</code>  能够说出组件的销毁阶段的钩子函数以及执行时机</p>
<table>
<thead>
<tr>
<th>钩子函数</th>
<th>触发时机</th>
<th>作用</th>
</tr>
</thead>
<tbody><tr>
<td>componentWillUnmount</td>
<td>组件卸载（从页面中消失）</td>
<td>执行清理工作（比如：清理定时器等）</td>
</tr>
</tbody></table>
<h2 id="阶段小练习-todoMVC"><a href="#阶段小练习-todoMVC" class="headerlink" title="阶段小练习 - todoMVC"></a>阶段小练习 - todoMVC</h2><p>案例仓库地址：<a target="_blank" rel="noopener" href="https://gitee.com/react-course-series/react-todo-mvc">https://gitee.com/react-course-series/react-todo-mvc</a></p>
<p>1- 克隆项目到本地 </p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ git <span class="hljs-built_in">clone</span>  https://gitee.com/react-course-series/react-todo-mvc.git<br></code></pre></td></tr></table></figure>

<p>2- 安装必要依赖 </p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ yarn<br></code></pre></td></tr></table></figure>



<p>3- 开启mock接口服务，<strong>保持窗口不关闭</strong>  ！！！！！ </p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 启动mock服务</span><br>$ yarn mock-serve<br></code></pre></td></tr></table></figure>

<p><strong>4- 另起一个bash窗口</strong>开启前端服务 </p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ yarn start<br></code></pre></td></tr></table></figure>

<p>5- 切换到todo-test分支 </p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ git checkout todo-test<br></code></pre></td></tr></table></figure>

<p><strong>接口文档</strong>  </p>
<table>
<thead>
<tr>
<th>接口作用</th>
<th>接口地址</th>
<th>接口方法</th>
<th>接口参数</th>
</tr>
</thead>
<tbody><tr>
<td>获取列表</td>
<td><a target="_blank" rel="noopener" href="http://localhost:3001/data">http://localhost:3001/data</a></td>
<td>GET</td>
<td>无</td>
</tr>
<tr>
<td>删除</td>
<td><a target="_blank" rel="noopener" href="http://localhost:3001/data/:id">http://localhost:3001/data/:id</a></td>
<td>DELETE</td>
<td>id</td>
</tr>
<tr>
<td>搜索</td>
<td><a target="_blank" rel="noopener" href="http://localhost:3001/data/?q=keyword">http://localhost:3001/data/?name=keyword</a></td>
<td>GET</td>
<td>name（以name字段搜索）</td>
</tr>
</tbody></table>
<p><strong>实现功能</strong></p>
<table>
<thead>
<tr>
<th>功能</th>
<th>核心思路</th>
</tr>
</thead>
<tbody><tr>
<td>表格数据渲染</td>
<td>组件使用</td>
</tr>
<tr>
<td>删除功能</td>
<td>获取当前id  调用接口</td>
</tr>
<tr>
<td>搜索功能</td>
<td>用的依旧是列表接口，多传一个name参数</td>
</tr>
<tr>
<td>清除搜索功能</td>
<td>清空搜索参数  重新获取列表</td>
</tr>
</tbody></table>
<h1 id="Hooks基础"><a href="#Hooks基础" class="headerlink" title="Hooks基础"></a>Hooks基础</h1><h2 id="Hooks概念理解"><a href="#Hooks概念理解" class="headerlink" title="Hooks概念理解"></a>Hooks概念理解</h2><p><code>本节任务:</code> 能够理解hooks的概念及解决的问题</p>
<h3 id="1-什么是hooks"><a href="#1-什么是hooks" class="headerlink" title="1. 什么是hooks"></a>1. 什么是hooks</h3><p>Hooks的本质：<strong>一套能够使函数组件更强大，更灵活的“钩子”</strong></p>
<p>React体系里组件分为 类组件 和 函数组件</p>
<p>经过多年的实战，函数组件是一个更加匹配React的设计理念 <code>UI = f(data)</code>，也更有利于逻辑拆分与重用的组件表达形式，而先前的函数组件是不可以有自己的状态的，为了能让函数组件可以拥有自己的状态，所以从react v16.8开始，Hooks应运而生</p>
<p><strong>注意点：</strong></p>
<ol>
<li>有了hooks之后，为了兼容老版本，class类组件并没有被移除，俩者都可以使用</li>
<li>有了hooks之后，不能在把函数成为无状态组件了，因为hooks为函数组件提供了状态</li>
<li>hooks只能在函数组件中使用</li>
</ol>
<h3 id="2-Hooks解决了什么问题"><a href="#2-Hooks解决了什么问题" class="headerlink" title="2. Hooks解决了什么问题"></a>2. Hooks解决了什么问题</h3><p>Hooks的出现解决了俩个问题   1. 组件的状态逻辑复用  2.class组件自身的问题</p>
<ol>
<li>组件的逻辑复用<br>   在hooks出现之前，react先后尝试了 mixins混入，HOC高阶组件，render-props等模式<br>   但是都有各自的问题，比如mixin的数据来源不清晰，高阶组件的嵌套问题等等 </li>
<li>class组件自身的问题<br>   class组件就像一个厚重的‘战舰’ 一样，大而全，提供了很多东西，有不可忽视的学习成本，比如各种生命周期，this指向问题等等，而我们更多时候需要的是一个轻快灵活的’快艇’</li>
</ol>
<h2 id="useState"><a href="#useState" class="headerlink" title="useState"></a>useState</h2><h3 id="1-基础使用"><a href="#1-基础使用" class="headerlink" title="1. 基础使用"></a>1. 基础使用</h3><p><code>本节任务:</code> 能够学会useState的基础用法</p>
<p><strong>作用</strong></p>
<p>useState为函数组件提供状态（state）</p>
<p><strong>使用步骤</strong></p>
<ol>
<li>导入 <code>useState</code> 函数</li>
<li>调用 <code>useState</code> 函数，并传入状态的初始值</li>
<li>从<code>useState</code>函数的返回值中，拿到状态和修改状态的方法</li>
<li>在JSX中展示状态</li>
<li>调用修改状态的方法更新状态</li>
</ol>
<p><strong>代码实现</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-comment">// 参数：状态初始值比如,传入 0 表示该状态的初始值为 0</span><br>  <span class="hljs-comment">// 返回值：数组,包含两个值：1 状态值（state） 2 修改该状态的函数（setState）</span><br>  <span class="hljs-keyword">const</span> [count, setCount] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">0</span>)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> &#123; setCount(count + 1) &#125;&#125;&gt;&#123;count&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h3 id="2-状态的读取和修改"><a href="#2-状态的读取和修改" class="headerlink" title="2. 状态的读取和修改"></a>2. 状态的读取和修改</h3><p><code>本节任务:</code> 能够理解useState下状态的读取和修改</p>
<p><strong>读取状态</strong></p>
<p>该方式提供的状态，是函数内部的局部变量，可以在函数内的任意位置使用</p>
<p><strong>修改状态</strong></p>
<ol>
<li>setCount是一个函数，参数表示<code>最新的状态值</code></li>
<li>调用该函数后，将使用新值替换旧值</li>
<li>修改状态后，由于状态发生变化，会引起视图变化</li>
</ol>
<p><strong>注意事项</strong></p>
<ol>
<li>修改状态的时候，一定要使用新的状态替换旧的状态，不能直接修改旧的状态，尤其是引用类型</li>
</ol>
<h3 id="3-组件的更新过程"><a href="#3-组件的更新过程" class="headerlink" title="3. 组件的更新过程"></a>3. 组件的更新过程</h3><p><code>本节任务:</code>  能够理解使用hook之后组件的更新情况</p>
<p>函数组件使用 <strong>useState</strong> hook 后的执行过程，以及状态值的变化</p>
<ul>
<li>组件第一次渲染</li>
</ul>
<ol>
<li><ol>
<li>从头开始执行该组件中的代码逻辑</li>
<li>调用 <code>useState(0)</code> 将传入的参数作为状态初始值，即：0</li>
<li>渲染组件，此时，获取到的状态 count 值为： 0</li>
</ol>
</li>
</ol>
<ul>
<li>组件第二次渲染</li>
</ul>
<ol>
<li><ol>
<li>点击按钮，调用 <code>setCount(count + 1)</code> 修改状态，因为状态发生改变，所以，该组件会重新渲染</li>
<li>组件重新渲染时，会再次执行该组件中的代码逻辑</li>
<li>再次调用 <code>useState(0)</code>，此时 <strong>React 内部会拿到最新的状态值而非初始值</strong>，比如，该案例中最新的状态值为 1</li>
<li>再次渲染组件，此时，获取到的状态 count 值为：1</li>
</ol>
</li>
</ol>
<p>注意：<strong>useState 的初始值(参数)只会在组件第一次渲染时生效</strong>。也就是说，以后的每次渲染，useState 获取到都是最新的状态值，React 组件会记住每次最新的状态值</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [count, setCount] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">0</span>)<br>  <span class="hljs-comment">// 在这里可以进行打印测试</span><br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(count)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> &#123; setCount(count + 1) &#125;&#125;&gt;&#123;count&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h3 id="4-使用规则"><a href="#4-使用规则" class="headerlink" title="4. 使用规则"></a>4. 使用规则</h3><p><code>本节任务:</code>  能够记住useState的使用规则</p>
<ol>
<li><code>useState</code> 函数可以执行多次，每次执行互相独立，每调用一次为函数组件提供一个状态</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">List</span>(<span class="hljs-params"></span>)&#123;<br>  <span class="hljs-comment">// 以字符串为初始值</span><br>  <span class="hljs-keyword">const</span> [name, setName] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;cp&#x27;</span>)<br>  <span class="hljs-comment">// 以数组为初始值</span><br>  <span class="hljs-keyword">const</span> [list,setList] = <span class="hljs-title function_">useState</span>([])<br>&#125;<br></code></pre></td></tr></table></figure>

<ol>
<li><p><code>useState</code> 注意事项 </p>
</li>
<li><ol>
<li>只能出现在函数组件或者其他hook函数中 </li>
<li>不能嵌套在if&#x2F;for&#x2F;其它函数中（react按照hooks的调用顺序识别每一个hook）</li>
</ol>
</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> num = <span class="hljs-number">1</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">List</span>(<span class="hljs-params"></span>)&#123;<br>  num++<br>  <span class="hljs-keyword">if</span>(num / <span class="hljs-number">2</span> === <span class="hljs-number">0</span>)&#123;<br>     <span class="hljs-keyword">const</span> [name, setName] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;cp&#x27;</span>) <br>  &#125;<br>  <span class="hljs-keyword">const</span> [list,setList] = <span class="hljs-title function_">useState</span>([])<br>&#125;<br><span class="hljs-comment">// 俩个hook的顺序不是固定的，这是不可以的！！！</span><br></code></pre></td></tr></table></figure>

<ol>
<li><ol>
<li>可以通过开发者工具查看hooks状态</li>
</ol>
</li>
</ol>
<h2 id="useEffect"><a href="#useEffect" class="headerlink" title="useEffect"></a>useEffect</h2><h3 id="1-理解函数副作用"><a href="#1-理解函数副作用" class="headerlink" title="1. 理解函数副作用"></a>1. 理解函数副作用</h3><p><code>本节任务:</code> 能够理解副作用的概念</p>
<p><strong>什么是副作用</strong></p>
<p>副作用是相对于主作用来说的，一个函数除了主作用，其他的作用就是副作用。对于 React 组件来说，<strong>主作用就是根据数据（state&#x2F;props）渲染 UI</strong>，除此之外都是副作用（比如，手动修改 DOM）</p>
<p><strong>常见的副作用</strong></p>
<ol>
<li>数据请求 ajax发送</li>
<li>手动修改dom</li>
<li>localstorage操作</li>
</ol>
<p>useEffect函数的作用就是为react函数组件提供副作用处理的！</p>
<h3 id="2-基础使用"><a href="#2-基础使用" class="headerlink" title="2. 基础使用"></a>2. 基础使用</h3><p><code>本节任务:</code> 能够学会useEffect的基础用法并且掌握默认的执行执行时机</p>
<p><strong>作用</strong></p>
<p>为react函数组件提供副作用处理</p>
<p><strong>使用步骤</strong></p>
<ol>
<li>导入 <code>useEffect</code> 函数</li>
<li>调用 <code>useEffect</code> 函数，并传入回调函数</li>
<li>在回调函数中编写副作用处理（dom操作）</li>
<li>修改数据状态</li>
<li>检测副作用是否生效</li>
</ol>
<p><strong>代码实现</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useEffect, useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [count, setCount] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">0</span>)<br> <br>  <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">()=&gt;</span>&#123;<br>    <span class="hljs-comment">// dom操作</span><br>    <span class="hljs-variable language_">document</span>.<span class="hljs-property">title</span> = <span class="hljs-string">`当前已点击了<span class="hljs-subst">$&#123;count&#125;</span>次`</span><br>  &#125;)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> &#123; setCount(count + 1) &#125;&#125;&gt;&#123;count&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h3 id="3-依赖项控制执行时机"><a href="#3-依赖项控制执行时机" class="headerlink" title="3. 依赖项控制执行时机"></a>3. 依赖项控制执行时机</h3><p><code>本节任务:</code> 能够学会使用依赖项控制副作用的执行时机</p>
<p><strong>1. 不添加依赖项</strong></p>
<p>组件首次渲染执行一次，以及不管是哪个状态更改引起组件更新时都会重新执行</p>
<ol>
<li>组件初始渲染</li>
<li>组件更新 （不管是哪个状态引起的更新）</li>
</ol>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-title function_">useEffect</span>(<span class="hljs-function">()=&gt;</span>&#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;副作用执行了&#x27;</span>)<br>&#125;)<br></code></pre></td></tr></table></figure>



<p><strong>2. 添加空数组</strong></p>
<p>组件只在首次渲染时执行一次</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-title function_">useEffect</span>(<span class="hljs-function">()=&gt;</span>&#123;<br>	 <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;副作用执行了&#x27;</span>)<br>&#125;,[])<br></code></pre></td></tr></table></figure>



<p><strong>3. 添加特定依赖项</strong></p>
<p>副作用函数在首次渲染时执行，在依赖项发生变化时重新执行</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;  <br>    <span class="hljs-keyword">const</span> [count, setCount] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">0</span>)  <br>    <span class="hljs-keyword">const</span> [name, setName] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;zs&#x27;</span>) <br>    <br>    <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;    <br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;副作用执行了&#x27;</span>)  <br>    &#125;, [count])  <br>    <br>    <span class="hljs-keyword">return</span> (    <br>        <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span>      </span><br><span class="language-xml">         <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> &#123; setCount(count + 1) &#125;&#125;&gt;&#123;count&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>      </span><br><span class="language-xml">         <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> &#123; setName(&#x27;cp&#x27;) &#125;&#125;&gt;&#123;name&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>    </span><br><span class="language-xml">        <span class="hljs-tag">&lt;/&gt;</span></span>  <br>    )<br>&#125;<br></code></pre></td></tr></table></figure>



<p><strong>注意事项</strong></p>
<p>useEffect 回调函数中用到的数据（比如，count）就是依赖数据，就应该出现在依赖项数组中，如果不添加依赖项就会有bug出现</p>
<h3 id="4-清理副作用"><a href="#4-清理副作用" class="headerlink" title="4. 清理副作用"></a>4. 清理副作用</h3><p>如果想要清理副作用 可以在副作用函数中的末尾return一个新的函数，在新的函数中编写清理副作用的逻辑</p>
<p>注意执行时机为：</p>
<ol>
<li>组件卸载时自动执行</li>
<li>组件更新时，下一个useEffect副作用函数执行之前自动执行</li>
</ol>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useEffect, useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;react&quot;</span><br><br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">App</span> = (<span class="hljs-params"></span>) =&gt; &#123;<br>  <span class="hljs-keyword">const</span> [count, setCount] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">0</span>)<br>  <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-keyword">const</span> timerId = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>      <span class="hljs-title function_">setCount</span>(count + <span class="hljs-number">1</span>)<br>    &#125;, <span class="hljs-number">1000</span>)<br>    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> &#123;<br>      <span class="hljs-comment">// 用来清理副作用的事情</span><br>      <span class="hljs-built_in">clearInterval</span>(timerId)<br>    &#125;<br>  &#125;, [count])<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      &#123;count&#125;</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="阶段小练习-自定义hook"><a href="#阶段小练习-自定义hook" class="headerlink" title="阶段小练习 - 自定义hook"></a>阶段小练习 - 自定义hook</h2><p><strong>需求描述</strong>：自定义一个hook函数，实现获取滚动距离Y</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> [y] = <span class="hljs-title function_">useWindowScroll</span>()<br><span class="hljs-keyword">import</span> &#123; useState, useEffect &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;react&quot;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">useWindowScroll</span> () &#123;<br>  <span class="hljs-keyword">const</span> [y, setY] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">0</span>)<br>  <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">()=&gt;</span>&#123;<br>     <span class="hljs-keyword">const</span> <span class="hljs-title function_">scrollHandler</span> = (<span class="hljs-params"></span>) =&gt; &#123;<br>        <span class="hljs-keyword">const</span> h = <span class="hljs-variable language_">document</span>.<span class="hljs-property">documentElement</span>.<span class="hljs-property">scrollTop</span><br>        <span class="hljs-title function_">setY</span>(h)<br>     &#125;)<br>     <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;scroll&#x27;</span>, scrollHandler)<br>     <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">removeEventListener</span>(<span class="hljs-string">&#x27;scroll&#x27;</span>, scrollHandler)<br>  &#125;)<br> <br>  <span class="hljs-keyword">return</span> [y]<br>&#125;<br></code></pre></td></tr></table></figure>



<p><strong>需求描述：</strong> 自定义hook函数，可以自动同步到本地LocalStorage</p>
<figure class="highlight pf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pf"><span class="hljs-keyword">const</span> [message, <span class="hljs-built_in">set</span>Message] = useLocalStorage(key，<span class="hljs-keyword">default</span>Value)<br></code></pre></td></tr></table></figure>

<ol>
<li>message可以通过自定义传入默认初始值</li>
<li>每次修改message数据的时候 都会自动往本地同步一份</li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> &#123; useEffect, useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">useLocalStorage</span> (key, defaultValue) &#123;<br>  <span class="hljs-keyword">const</span> [message, setMessage] = <span class="hljs-title function_">useState</span>(defaultValue)<br>  <span class="hljs-comment">// 每次只要message变化 就会自动同步到本地ls</span><br>  <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-variable language_">window</span>.<span class="hljs-property">localStorage</span>.<span class="hljs-title function_">setItem</span>(key, message)<br>  &#125;, [message, key])<br>  <span class="hljs-keyword">return</span> [message, setMessage]<br>&#125;<br></code></pre></td></tr></table></figure>



<h1 id="Hooks进阶"><a href="#Hooks进阶" class="headerlink" title="Hooks进阶"></a>Hooks进阶</h1><h2 id="useState-回调函数的参数"><a href="#useState-回调函数的参数" class="headerlink" title="useState - 回调函数的参数"></a>useState - 回调函数的参数</h2><p><code>本节任务:</code>  能够理解useState回调函数作为参数的使用场景</p>
<p><strong>使用场景</strong></p>
<p>参数只会在组件的初始渲染中起作用，后续渲染时会被忽略。如果初始 state 需要通过计算才能获得，则可以传入一个函数，在函数中计算并返回初始的 state，此函数只在初始渲染时被调用</p>
<p><strong>语法</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">const</span> [name, setName] = <span class="hljs-title function_">useState</span>(<span class="hljs-function">()=&gt;</span>&#123;   <br>  <span class="hljs-comment">// 编写计算逻辑    return &#x27;计算之后的初始值&#x27;</span><br>&#125;)<br></code></pre></td></tr></table></figure>



<p><strong>语法规则</strong></p>
<ol>
<li>回调函数return出去的值将作为 <code>name</code> 的初始值</li>
<li>回调函数中的逻辑只会在组件初始化的时候执行一次</li>
</ol>
<p><strong>语法选择</strong></p>
<ol>
<li>如果就是初始化一个普通的数据 直接使用 <code>useState(普通数据)</code> 即可</li>
<li>如果要初始化的数据无法直接得到需要通过计算才能获取到，使用<code>useState(()=&gt;&#123;&#125;)</code></li>
</ol>
<p><strong>来个需求</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Counter</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">const</span> [count, setCount] = <span class="hljs-title function_">useState</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-keyword">return</span> props.<span class="hljs-property">count</span><br>  &#125;)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> setCount(count + 1)&#125;&gt;&#123;count&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Counter</span> <span class="hljs-attr">count</span>=<span class="hljs-string">&#123;10&#125;</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Counter</span> <span class="hljs-attr">count</span>=<span class="hljs-string">&#123;20&#125;</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="useEffect-发送网络请求"><a href="#useEffect-发送网络请求" class="headerlink" title="useEffect - 发送网络请求"></a>useEffect - 发送网络请求</h2><p><code>本节任务:</code>  能够掌握使用useEffect hook发送网络请求</p>
<p><strong>使用场景</strong></p>
<p>如何在useEffect中发送网络请求，并且封装同步 async await操作</p>
<p><strong>语法要求</strong></p>
<p>不可以直接在useEffect的回调函数外层直接包裹 await ，因为<strong>异步会导致清理函数无法立即返回</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-title function_">useEffect</span>(<span class="hljs-keyword">async</span> ()=&gt;&#123;    <br>    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;http://geek.itheima.net/v1_0/channels&#x27;</span>)   <br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res)<br>&#125;,[])<br></code></pre></td></tr></table></figure>



<p><strong>正确写法</strong></p>
<p>在内部单独定义一个函数，然后把这个函数包装成同步</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-title function_">useEffect</span>(<span class="hljs-function">()=&gt;</span>&#123;   <br>    <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">fetchData</span>(<span class="hljs-params"></span>)&#123;      <br>       <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.<span class="hljs-title function_">get</span>(<span class="hljs-string">&#x27;http://geek.itheima.net/v1_0/channels&#x27;</span>)                            <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(res)   <br>    &#125; <br>&#125;,[])<br></code></pre></td></tr></table></figure>



<h2 id="useRef"><a href="#useRef" class="headerlink" title="useRef"></a>useRef</h2><p><code>本节任务:</code>  能够掌握使用useRef获取真实dom或组件实例的方法</p>
<p><strong>使用场景</strong></p>
<p>在函数组件中获取真实的dom元素对象或者是组件对象</p>
<p><strong>使用步骤</strong></p>
<ol>
<li>导入 <code>useRef</code> 函数</li>
<li>执行 <code>useRef</code> 函数并传入null，返回值为一个对象 内部有一个current属性存放拿到的dom对象（组件实例）</li>
<li>通过ref 绑定 要获取的元素或者组件</li>
</ol>
<p><strong>获取dom</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useEffect, useRef &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;  <br>    <span class="hljs-keyword">const</span> h1Ref = <span class="hljs-title function_">useRef</span>(<span class="hljs-literal">null</span>)  <br>    <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;    <br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(h1Ref)  <br>    &#125;,[])  <br>    <span class="hljs-keyword">return</span> (    <br>        <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>      </span><br><span class="language-xml">            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&#123;</span> <span class="hljs-attr">h1Ref</span> &#125;&gt;</span>this is h1<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>    </span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>  <br>    )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<p><strong>获取组件实例</strong></p>
<p>函数组件由于没有实例，不能使用ref获取，如果想获取组件实例，必须是类组件</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Foo</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;  <br>    sayHi = <span class="hljs-function">() =&gt;</span> &#123;    <br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;say hi&#x27;</span>)  <br>    &#125;  <br>    <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>)&#123;    <br>        <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Foo<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>  <br>    &#125;<br>&#125;<br>    <br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">Foo</span><br></code></pre></td></tr></table></figure>





<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useEffect, useRef &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Foo</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./Foo&#x27;</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;  <br>    <span class="hljs-keyword">const</span> h1Foo = <span class="hljs-title function_">useRef</span>(<span class="hljs-literal">null</span>)  <br>    <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;    <br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(h1Foo)  <br>    &#125;, [])  <br>    <span class="hljs-keyword">return</span> (    <br>        <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">Foo</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&#123;</span> <span class="hljs-attr">h1Foo</span> &#125; /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>  <br>    )<br>&#125;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="useContext"><a href="#useContext" class="headerlink" title="useContext"></a>useContext</h2><p><code>本节任务:</code>  能够掌握hooks下的context使用方式</p>
<p><strong>实现步骤</strong></p>
<ol>
<li>使用<code>createContext</code> 创建Context对象</li>
<li>在顶层组件通过<code>Provider</code> 提供数据</li>
<li>在底层组件通过<code>useContext</code>函数获取数据</li>
</ol>
<p><strong>代码实现</strong></p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; createContext, useContext &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-comment">// 创建Context对象</span><br><span class="hljs-keyword">const</span> <span class="hljs-title class_">Context</span> = <span class="hljs-title function_">createContext</span>()<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Foo</span>(<span class="hljs-params"></span>) &#123;  <br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Foo <span class="hljs-tag">&lt;<span class="hljs-name">Bar</span>/&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Bar</span>(<span class="hljs-params"></span>) &#123;  <br>    <span class="hljs-comment">// 底层组件通过useContext函数获取数据  </span><br>    <span class="hljs-keyword">const</span> name = <span class="hljs-title function_">useContext</span>(<span class="hljs-title class_">Context</span>)  <br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Bar &#123;name&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&#125;<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;  <br>    <span class="hljs-keyword">return</span> (    <br>        <span class="hljs-comment">// 顶层组件通过Provider 提供数据    </span><br>        <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Context.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&#123;</span>&#x27;<span class="hljs-attr">this</span> <span class="hljs-attr">is</span> <span class="hljs-attr">name</span>&#x27;&#125;&gt;</span>     </span><br><span class="language-xml">            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">Foo</span>/&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>    </span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">Context.Provider</span>&gt;</span></span>  <br>    )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>



<h2 id="阶段小练习-todoMvc-hook版"><a href="#阶段小练习-todoMvc-hook版" class="headerlink" title="阶段小练习-todoMvc-hook版"></a>阶段小练习-todoMvc-hook版</h2><p>案例仓库地址：<a target="_blank" rel="noopener" href="https://gitee.com/react-course-series/react-tomvc-hook">https://gitee.com/react-course-series/react-tomvc-hook</a></p>
<ol>
<li>克隆项目到本地</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ git <span class="hljs-built_in">clone</span>  https://gitee.com/react-course-series/react-tomvc-hook.git<br></code></pre></td></tr></table></figure>

<ol>
<li>安装必要依赖</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ yarn<br></code></pre></td></tr></table></figure>

<ol>
<li>开启mock接口服务，<strong>保持窗口不关闭</strong>  ！！！！！</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 启动mock服务</span><br>$ yarn mock-serve<br></code></pre></td></tr></table></figure>

<ol>
<li><strong>另起一个bash窗口</strong>开启前端服务</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ yarn start<br></code></pre></td></tr></table></figure>

<ol>
<li>浏览器输入 localhost:3000演示效果</li>
</ol>
<p><strong>项目开发步骤：</strong></p>
<ol>
<li>切换到todo-test分支</li>
</ol>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ git checkout todo-test<br></code></pre></td></tr></table></figure>

<ol>
<li>打开 app.js<br>   已有基础样板代码，在这个基础上编写业务逻辑即可 </li>
<li>接口文档</li>
</ol>
<table>
<thead>
<tr>
<th>接口作用</th>
<th>接口地址</th>
<th>接口方法</th>
<th>接口参数</th>
</tr>
</thead>
<tbody><tr>
<td>获取列表</td>
<td><a target="_blank" rel="noopener" href="http://localhost:3001/data">http://localhost:3001/data</a></td>
<td>GET</td>
<td>无</td>
</tr>
<tr>
<td>删除</td>
<td><a target="_blank" rel="noopener" href="http://localhost:3001/data/:id">http://localhost:3001/data/:id</a></td>
<td>DELETE</td>
<td>id</td>
</tr>
<tr>
<td>搜索</td>
<td><a target="_blank" rel="noopener" href="http://localhost:3001/data/?q=keyword">http://localhost:3001/data/?name=keyword</a></td>
<td>GET</td>
<td>name（以name字段搜索）</td>
</tr>
</tbody></table>
<p><strong>实现功能</strong></p>
<table>
<thead>
<tr>
<th>功能</th>
<th>核心思路</th>
</tr>
</thead>
<tbody><tr>
<td>表格数据渲染</td>
<td>elementPlus el-table组件使用</td>
</tr>
<tr>
<td>删除功能</td>
<td>获取当前id  调用接口</td>
</tr>
<tr>
<td>搜索功能</td>
<td>用的依旧是列表接口，多传一个name参数</td>
</tr>
<tr>
<td>清除搜索功能</td>
<td>清空搜索参数  重新获取列表</td>
</tr>
</tbody></table>

                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/categories/React/" class="category-chain-item">React</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/tags/React/">#React</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>React基础</div>
      <div>http://example.com/2023/06/02/编程语言/React/01.React基础/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>深海火锅店</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2023年6月2日</div>
        </div>
      
      
      
        <div class="license-meta-item">
          <div>许可协议</div>
          <div>
            
              
              
                <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
                  <span class="hint--top hint--rounded" aria-label="BY - 署名">
                    <i class="iconfont icon-by"></i>
                  </span>
                </a>
              
            
          </div>
        </div>
      
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2023/06/03/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/React/03.Mobx/" title="03.Mobx">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">03.Mobx</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2023/05/30/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/%E5%AD%A6%E4%B9%A0/%E6%A1%86%E6%9E%B6/Elasticsearct/Elasticsearct%E5%AD%A6%E4%B9%A0/" title="elasticsearch学习">
                        <span class="hidden-mobile">elasticsearch学习</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
    </div>
  
  
    <div class="statistics">
  
  

  
    
      <span id="busuanzi_container_site_pv" style="display: none">
        总访问量 
        <span id="busuanzi_value_site_pv"></span>
         次
      </span>
    
    
      <span id="busuanzi_container_site_uv" style="display: none">
        总访客数 
        <span id="busuanzi_value_site_uv"></span>
         人
      </span>
    
    
  
</div>

  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init(Object.assign({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      scrollSmooth    : true,
      includeTitleTags: true,
      headingsOffset  : -boardTop,
    }, CONFIG.toc));
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }

    Fluid.events.registerRefreshCallback(function() {
      if ('tocbot' in window) {
        tocbot.refresh();
        var toc = jQuery('#toc');
        if (toc.length === 0 || !tocbot) {
          return;
        }
        if (toc.find('.toc-list-item').length > 0) {
          toc.css('visibility', 'visible');
        }
      }
    });
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.11/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));

    Fluid.events.registerRefreshCallback(function() {
      if ('anchors' in window) {
        anchors.removeAll();
        var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
        var res = [];
        for (var item of el) {
          res.push('.markdown-body > ' + item.trim());
        }
        if (CONFIG.anchorjs.placement === 'left') {
          anchors.options.class = 'anchorjs-link-left';
        }
        anchors.add(res.join(', '));
      }
    });
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/js/local-search.js" ></script>

  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>




  
<script src="//cdn.jsdelivr.net/gh/EmoryHuang/BlogBeautify@1.1/DynamicRibbon.min.js"></script>



<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
